/*
 * @Author: wangdazhuang
 * @Date: 2024-08-19 11:56:27
 * @LastEditors: wangdazhuang
 * @Description: 
 * @FilePath: /pornhub_app/lib/views/player/controllers/video_play_controller.dart
 */

import 'dart:async';
import 'dart:math';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:media_kit/media_kit.dart';
import 'package:media_kit_video/media_kit_video.dart';
import 'package:pornhub_app/components/common_permission_alert.dart';
import 'package:pornhub_app/http/api/api.dart';
import 'package:pornhub_app/env/environment_service.dart';
import 'package:pornhub_app/http/http_service.dart';
import 'package:pornhub_app/model/advertisements/ad_resp_model.dart';
import 'package:pornhub_app/model/play/cdn_model.dart';
import 'package:pornhub_app/model/play/video_detail_model.dart';
import 'package:pornhub_app/services/user_service.dart';
import 'package:pornhub_app/utils/enum.dart';
import 'package:pornhub_app/utils/initAdvertisementInfo.dart';
import 'package:pornhub_app/utils/logger.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:pornhub_app/views/player/views/av_permission_ui.dart';
import '../../../model/video_base_model.dart';
import '../../../routes/routes.dart';

class VideoPlayController extends GetxController {
  static const aspRatio = 400 / 236.0;
  static double get videoH => Get.width / aspRatio;

  bool _requesting = false;
  bool playerInitialized = false;

  VideoDetail currentVideo = VideoDetail.fromJson({});
  List<VideoBaseModel> guessLikeItems = List<VideoBaseModel>.of([]);

  List<CdnRsp> lines = [];
  final us = Get.find<UserService>();
  late CdnRsp selectCdn;
  bool showTip = false;
  bool isCollect = false;
  static const permissionDialogTag = 'videoplayerrrrrr';

  VideoController? playerVC;
  Player? player;

  Duration _currentPos = Duration.zero;
  // ignore: unused_field
  Duration _durationPos = Duration.zero;
  StreamSubscription<Duration>? _currentPosSubs;
  StreamSubscription<bool>? _completePosSubs;
  StreamSubscription<String>? _errorSubs;
  StreamSubscription<Duration>? _durationSubs;
  StreamSubscription<bool>? _playingSubs;

  ///左下角倒计时广告
  int adTimerCount = 0;
  bool showMarkAd = false;
  Timer? timer;
  var markAd = initWeightAdvertisementInfo(AdPlaceNameEnum.PLAY_MARK);

  ///暂停广告
  AdvertisementInfos? stopAd;
  bool showStopAd = false;

  ///左下角小图标广告
  void resetleftBottomAd() {
    timer?.cancel();
    showMarkAd = false;
    markAd = initWeightAdvertisementInfo(AdPlaceNameEnum.PLAY_MARK);
    if (markAd != null) {
      adTimerCount = markAd!.minStaySecond ?? 15;
    }
  }

  ///左下角倒计时
  _leftBottomAdCountDown() {
    if (markAd == null) return;
    timer = Timer.periodic(
      const Duration(seconds: 1),
      (timer) {
        if (adTimerCount > 0) {
          adTimerCount -= 1;
        }
        _updateController();
      },
    );
  }

  void _updateController() => update();

  ///暂停广告
  void resetStopAd() {
    final items = initSequenceAdvertisementInfo(AdPlaceNameEnum.VIDEO_PAUSED);
    if (items.isNotEmpty) {
      final randomIndex = Random().nextInt(items.length);
      stopAd = items[randomIndex];
    }
  }

  ///切换暂停广告
  void toggleShowStopAd() {
    showStopAd = !showStopAd;
    _updateController();
  }

  @override
  void onInit() {
    us.updateAPIAssetsInfo();
    final id = int.tryParse(Get.parameters['id'] ?? '') ?? 0;
    getVideoById(id);
    getAllLines();

    super.onInit();
  }

  ///切换播放源
  Future getVideoById(int videoId) async {
    if (_requesting) return;
    _requesting = true;
    resetleftBottomAd();
    resetStopAd();
    final resp = await Api.fetchVideoDetailById(videoId: videoId);
    if (resp == null) return;
    currentVideo = resp;
    _updateController();
    final playPath = Uri.parse(currentVideo.playPath ?? '');
    changePlayPath(playPath);
    _getGuessLikeList(videoId: videoId);
  }

  ///更换播放源
  changePlayPath(Uri _) async {
    _currentPos = Duration.zero;
    _durationPos = Duration.zero;
    playerInitialized = false;
    showTip = false;
    _updateController();
    await player?.stop();
    _dispose();

    final videoURL = _.toString();
    logger.d("playPath:>>>>$videoURL");
    _requesting = false;
    final config = PlayerConfiguration(
      muted: false, //web下静音可以实现自动播放
      title: '',
      osc: true,
      ready: () {
        playerInitialized = true;
        _updateController();
      },
    );
    player = Player(configuration: config);
    playerVC = VideoController(player!,
        configuration: const VideoControllerConfiguration(
            androidAttachSurfaceAfterVideoParameters: true));
    player!.open(Media(videoURL));
    _addVideoListeners();
  }

  ///添加监听器
  void _addVideoListeners() {
    ///当前进度信息
    _currentPosSubs = player!.stream.position.listen((event) {
      _currentPos = event;
    });

    ///是否正在播放
    _playingSubs = player!.stream.playing.listen((event) {
      if (event) {
        ///正在播放
        if (!showMarkAd && adTimerCount > 0) {
          showMarkAd = true;
          _leftBottomAdCountDown();
        }
        if (showStopAd) {
          toggleShowStopAd();
        }
      } else {
        ///暂停了
        if (!showStopAd) {
          toggleShowStopAd();
        }
      }
    });

    ///时长
    _durationSubs = player!.stream.duration.listen((event) {
      _durationPos = event;
    });

    ///播放完成
    _completePosSubs = player!.stream.completed.listen((event) {
      if (event) {
        if (currentVideo.canWatch == false) {
          showTip = true;
          _updateController();
        }
      }
    });

    ///错误
    _errorSubs = player!.stream.error.listen((event) {
      logger.d('play error >>>>$event');
    });
  }

  ///视频宽高比
  double videoAsp() {
    var w = currentVideo.width ?? 400.0;
    if (w == 0) {
      w = 400.0;
    }
    var h = currentVideo.height ?? 236.0;
    if (h == 0) {
      h = 236.0;
    }
    final asp = w / h;
/**"height": 1920,
   "width": 1080, */
    return asp;
  }

  ///销毁
  void _dispose() {
    logger.d("destroy called,release memory!");
    _currentPosSubs?.cancel();
    _durationSubs?.cancel();
    _playingSubs?.cancel();
    _completePosSubs?.cancel();
    _errorSubs?.cancel();

    player?.dispose();
    uploadWatchRC();
  }

  @override
  void onClose() {
    _dispose();
    timer?.cancel();
    super.onClose();
  }

  ///切换线路
  void changeLine(CdnRsp resp) {
    selectCdn = resp;
    _updateController();
  }

  void sureChangeLine() {
    // currentVideo.cdnRes = selectCdn;
    changePlayPath(Environment.buildAuthPlayUrl(
        videoUrl: currentVideo.videoUrl,
        authKey: '', //currentVideo.authKey,
        id: selectCdn.id));
  }

  /// 权限弹框
  void showFullPermissionUI() {
    if (SmartDialog.checkExist(tag: VideoPlayController.permissionDialogTag)) {
      return;
    }
    SmartDialog.show(
      alignment: Alignment.center,
      clickMaskDismiss: true,
      tag: VideoPlayController.permissionDialogTag,
      useAnimation: false,
      keepSingle: true,
      builder: (context) {
        return AvPermissionUI(
          model: currentVideo,
          payAction: () {
            buyAction();
            SmartDialog.dismiss(tag: VideoPlayController.permissionDialogTag);
          },
        );
      },
    );
  }

  ///业务操作接口处理

  ///猜你喜欢
  Future _getGuessLikeList({required int videoId}) async {
    final items = await Api.fetchGuessLikeVideoList(videoId: videoId);
    if (items != null) {
      guessLikeItems = items;
      _updateController();
    }
  }

  //点赞
  Future likeAction() async {
    if (_requesting) {
      return;
    }
    _requesting = true;
    try {
      await httpInstance.post(
          url: currentVideo.like! ? 'video/cancelLike' : 'video/like',
          body: {"videoId": currentVideo.videoId!});
      _requesting = false;
      currentVideo.like = !currentVideo.like!;
      currentVideo.fakeLikes = currentVideo.like!
          ? currentVideo.fakeLikes! + 1
          : currentVideo.fakeLikes! - 1;
      _updateController();
    } catch (_) {
      _requesting = false;
    }
  }

  /// 购买
  Future buyAction() async {
    if (us.assets.gold! < currentVideo.price!) {
      permission_alert(
        Get.context!,
        desc: "余额不足,请前往充值",
        oktitle: "去充值",
        okAction: () {
          Get.toVip(tabInitIndex: 1);
        },
      );
      return;
    }
    if (_requesting) return;
    SmartDialog.showLoading(msg: "购买中...", alignment: Alignment.center);
    try {
      _requesting = true;
      final _ = await httpInstance.post(
          url: "tran/pur/video", body: {"videoId": currentVideo.videoId!});
      SmartDialog.dismiss();
      _requesting = false;
      currentVideo.canWatch = true;
      SmartDialog.showToast("购买成功!", alignment: Alignment.center);
      getVideoById(currentVideo.videoId!);
      us.updateAPIAssetsInfo();
    } catch (_) {
      _requesting = false;
      SmartDialog.dismiss();
    }
  }

  ///关注
  Future focusAction() async {
    if (_requesting) {
      return;
    }
    _requesting = true;
    final r = await Api.focusAction(
        userId: currentVideo.userId!, attention: currentVideo.attention!);
    _requesting = false;
    if (r) {
      currentVideo.attention = !currentVideo.attention!;
      _updateController();
    }
  }

  /// 获取全部的线路
  Future getAllLines() async {
    final rsp = await Api.fetchCdnLines();
    if (rsp != null) {
      lines = rsp;
    }
  }

  ///上报观影记录
  void uploadWatchRC() {
    if (!playerInitialized) return;
    if (currentVideo.canWatch == false) return;
    final currentSeconds = _currentPos.inSeconds;
    if (currentSeconds < 5) return;
    //上报
    Api.uploadWatchRc(
        duration: currentVideo.playTime ?? 0,
        lookType: _lookType(),
        videoId: currentVideo.videoId ?? 0,
        progress: currentSeconds);
  }

  ///观看方式 1:免费次数 2：vip观看 3： 金币观看 4：试看
  int _lookType() {
    /////视频类型：0-普通视频 1-VIP视频 2-付费视频
    int n = currentVideo.videoType!;
    switch (n) {
      case 0:
        return 1;
      case 1:
        return 2;
      case 2:
        return 3;
      default:
        return 0;
    }
  }
}
